/*
 * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
 */
package com.baidu.aip.face;

import android.graphics.Rect;
import android.graphics.RectF;

import com.baidu.aip.config.ImageFrame;


/**
 * 裁剪一定区域内的图片进行检测。
 */
public class DetectRegionProcessor implements FaceProcessor {

    private RectF detectedRect;

    private RectF originalCoordinate = new RectF();

    /**
     * 设置裁剪的区域。该区域内的图片被会裁剪进行检测，其余会被抛弃。
     *
     * @param rect 检测区域
     */
    public void setDetectedRect(RectF rect) {
        detectedRect = rect;
    }


    private Rect cropRect = new Rect();

    @Override
    public boolean process(FaceDetectManager faceDetectManager, ImageFrame frame) {
        if (detectedRect != null) {
            originalCoordinate.set(detectedRect);
            CameraImageSource cam = (CameraImageSource) faceDetectManager.getImageSource(); // TODO
            cam.getCameraControl().getPreviewView().mapToOriginalRect(originalCoordinate);
            cropRect.left = (int) originalCoordinate.left;
            cropRect.top = (int) originalCoordinate.top;
            cropRect.right = (int) originalCoordinate.right;
            cropRect.bottom = (int) originalCoordinate.bottom;
            frame.setArgb(FaceCropper.crop(frame.getArgb(), frame.getWidth(), cropRect));
            frame.setWidth(cropRect.width());
            frame.setHeight(cropRect.height());
        }
        return false;
    }

    @Override
    public boolean process2(FaceDetectManager detectManager, MyImageFrame frame) {
        if (detectedRect != null) {
            originalCoordinate.set(detectedRect);
            CameraImageSource cam = (CameraImageSource) detectManager.getImageSource(); // TODO
            cam.getCameraControl().getPreviewView().mapToOriginalRect(originalCoordinate);
            cropRect.left = (int) originalCoordinate.left;
            cropRect.top = (int) originalCoordinate.top;
            cropRect.right = (int) originalCoordinate.right;
            cropRect.bottom = (int) originalCoordinate.bottom;
            byte[] image = clipNV21(frame.getFrame(), frame.getWidth(), frame.getHeight(),
                    cropRect.left, cropRect.top,cropRect.width(),cropRect.height());
            frame.setFrame(image);
            frame.setWidth(cropRect.width());
            frame.setHeight(cropRect.height());
        }
        return false;
    }

    public static byte[] clipNV21(byte[] src, int width, int height, int left, int top, int clip_w, int clip_h) {
        if (left > width || top > height) {
            return null;
        }
        //取偶
        int x = left / 2 * 2, y = top / 2 * 2;
        int w = clip_w / 2 * 2, h = clip_h / 2 * 2;
        int y_unit = w * h;
        int uv = y_unit / 2;
        byte[] nData = new byte[y_unit + uv];
        int uv_index_dst = w * h - y / 2 * w;
        int uv_index_src = width * height + x;
        int srcPos0 = y * width;
        int destPos0 = 0;
        int uvSrcPos0 = uv_index_src;
        int uvDestPos0 = uv_index_dst;
        for (int i = y; i < y + h; i++) {
            System.arraycopy(src, srcPos0 + x, nData, destPos0, w);//y内存块复制
            srcPos0 += width;
            destPos0 += w;
            if ((i & 1) == 0) {
                System.arraycopy(src, uvSrcPos0, nData, uvDestPos0, w);//uv内存块复制
                uvSrcPos0 += width;
                uvDestPos0 += w;
            }
        }
        return nData;
    }
}
